package com.aim.analysis.yoachim;

import com.aim.analysis.artifact.AbstractArtifact;
import com.aim.analysis.artifact.ArtifactSubFolder;
import com.aim.analysis.records.Game;
import com.aim.analysis.records.GameValueExtractor;
import com.aim.analysis.records.Hit;
import com.aim.analysis.records.RecordType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * User: Avraham Shvartzon
 * Date: 7/8/14
 */
public class SplittedGamesReport extends AbstractArtifact{

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private String fileName;

    public SplittedGamesReport(String fileName) {
        this.fileName = fileName;
    }

    public static void main(String[] args) throws IOException {
        File splittedGameReportFile = new File("C:\\data\\Thesis\\spacegame\\resultAzure\\yoachim\\dividedGamesTest.xlsx");

        //List<Hit> hits = Hit.getHits("20140616", "20140619", "20140714");
        List<Hit> hits = Hit.getHits("Test");
        SplittedGamesReport splittedGamesReport = new SplittedGamesReport("nothing");
        splittedGamesReport.writeReport(hits, splittedGameReportFile);
    }

    private void writeReport(Collection<Hit> hits, File splittedGameReportFile) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Divided Games");

        writeHeader(sheet, gameValueExtractors);
        writeContent(sheet,hits, gameValueExtractors);
        workbook.write(new FileOutputStream(splittedGameReportFile));
    }

    private static void writeHeader(XSSFSheet sheet, List<GameValueExtractor> gameValueExtractors) {
        XSSFRow row = sheet.createRow(0);
        int cellIndex = 0;

        row.createCell(cellIndex++).setCellValue("Date");
        row.createCell(cellIndex++).setCellValue("partitionKey");
        row.createCell(cellIndex++).setCellValue("game with alert first");
        row.createCell(cellIndex++).setCellValue("netScore game1");

        String[] suffixes = {"a1", "a2", "b1", "b2"};
        for (int i = 0; i < 4; i++) {
            for (GameValueExtractor gameValueExtractor : gameValueExtractors) {
                row.createCell(cellIndex++).setCellValue(gameValueExtractor.name + " " + suffixes[i]);
            }
        }

    }

    private static void writeContent(XSSFSheet sheet, Collection<Hit> hits, List<GameValueExtractor> gameValueExtractors) {
        List<Hit> hitList = new ArrayList<Hit>(hits);
        for (int i = 0; i < hitList.size(); i++) {
            Hit hit = hitList.get(i);
            XSSFRow row = sheet.createRow(i + 1);
            writeHitContent(row, hit, gameValueExtractors);
        }
    }


    private static void writeHitContent(XSSFRow row, Hit hit, List<GameValueExtractor> gameValueExtractors) {
        int cellIndex = 0;

        HitWithDivideGames hitWithDivideGames = new HitWithDivideGames(hit);


        row.createCell(cellIndex++).setCellValue(dateFormat.format(hit.getDate()));
        row.createCell(cellIndex++).setCellValue(hit.assignmentId);
        row.createCell(cellIndex++).setCellValue(hitWithDivideGames.gameWithAlertFirst);
        row.createCell(cellIndex++).setCellValue(hit.gameList.get(0).getNetScore());

        for (int i = 0; i < hitWithDivideGames.games.length; i++) {
            Game game = hitWithDivideGames.games[i];

            for (GameValueExtractor gameValueExtractor : gameValueExtractors) {
                XSSFCell cell = row.createCell(cellIndex++);
                cell.setCellValue(gameValueExtractor.getValue(game).toString());
            }
        }
    }

    private static List<GameValueExtractor> gameValueExtractors;

    static {
        gameValueExtractors = new ArrayList<GameValueExtractor>();

        //mechanical - actions & costs
        gameValueExtractors.add(GameValueExtractor.maintenance);
        gameValueExtractors.add(GameValueExtractor.minor);
        gameValueExtractors.add(GameValueExtractor.moderate);
        gameValueExtractors.add(GameValueExtractor.severe);
        gameValueExtractors.add(GameValueExtractor.maintenanceCost);
        gameValueExtractors.add(GameValueExtractor.repairCost);
        gameValueExtractors.add(GameValueExtractor.mechanicalCost);

        gameValueExtractors.add(GameValueExtractor.numOfMaintenanceAfterAlert);
        gameValueExtractors.add(GameValueExtractor.numOfMalfunctionAfterAlert);
        gameValueExtractors.add(GameValueExtractor.firstEventAfterAlertDiff);

        //refuel - actions & costs
        gameValueExtractors.add(GameValueExtractor.refuelByStations);
        gameValueExtractors.add(GameValueExtractor.refuelByStationsCost);
        gameValueExtractors.add(GameValueExtractor.refuelBySpaceship);
        gameValueExtractors.add(GameValueExtractor.refuelBySpaceshipCost);
        gameValueExtractors.add(GameValueExtractor.totalRefuelCost);

        //time
        gameValueExtractors.add(GameValueExtractor.mechanicalTime);
        gameValueExtractors.add(GameValueExtractor.refuelBySpaceshipTime);
        gameValueExtractors.add(GameValueExtractor.freezeTime);
        //gameValueExtractors.add(GameValueExtractor.gameLength);


        //performance
        gameValueExtractors.add(GameValueExtractor.totalShutdown);
        gameValueExtractors.add(GameValueExtractor.totalCollision);
        gameValueExtractors.add(GameValueExtractor.totalFire);

        // score
        gameValueExtractors.add(GameValueExtractor.calculatedMechanicalCost);
        gameValueExtractors.add(GameValueExtractor.netScore);
        gameValueExtractors.add(GameValueExtractor.calculatedScore2);
    }

    @Override
    public ArtifactSubFolder getArtifactSubFolder() {
        return ArtifactSubFolder.DIVIDED_GAME;
    }

    @Override
    public boolean execute(Collection<Hit> hitCollection) throws Exception {
        File reportFile = new File(getArtifactFolder(), fileName + ".xlsx");
        writeReport(hitCollection, reportFile);
        return true;
    }

    @Override
    protected String getFileNameSuffix() {
        return "";
    }
}
